package com.dji.ux.sample.MediaManager;

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.Log;

import androidx.annotation.NonNull;

import com.dji.ux.sample.CompleteWidgetActivity;
import com.dji.ux.sample.MQSignalClient.RabbitMQUtils;
import com.dji.ux.sample.Utils.GPSUtil;
import com.dji.ux.sample.Utils.SpUtils;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

import dji.common.error.DJIError;
import dji.common.flightcontroller.LocationCoordinate3D;
import dji.keysdk.DJIKey;
import dji.keysdk.FlightControllerKey;
import dji.keysdk.callback.GetCallback;
import dji.sdk.sdkmanager.DJISDKManager;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.ConnectionPool;
import okhttp3.MediaType;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class MediaUploadUtil {

    private static String TAG = "MediaUploadUtil";
    public static String token1 = "pjtqkUEz2R0/gbB0P2Vfx1YK+H0fdRPmiYaiLxfcUYHX4Vextoe5UWuNeaQfPDYJ";
    private static boolean onMission = false;
    private static String serverAdd = "http://8.134.15.236:10008/illegal";
    private static List<String> nodeIDs = new ArrayList<>();
    private static String curNodeID = "";
    private static HashMap<String, String> uploadMap = new HashMap<>();
    private static Context mcontext;
    private static OnUploadListener uploadListener;
    //    public static int nodeidIndx = 0;

    private static void post(Request request, okhttp3.Callback callback) {
        OkHttpClient client = new OkHttpClient().newBuilder()
                .connectTimeout(120, TimeUnit.SECONDS)
                .readTimeout(120, TimeUnit.SECONDS)
                .writeTimeout(120, TimeUnit.SECONDS)
                .connectionPool(new ConnectionPool(32, 5, TimeUnit.MINUTES))
                .build();
        client.newCall(request).enqueue(callback);
    }


    public static void prepareUploadData(Context context, List<String> nodes, OnUploadListener onUploadListener) {
        uploadListener = onUploadListener;
        uploadMap.clear();
        onMission = true;
        nodeIDs = nodes;
        mcontext = context;
        for (String id : nodes) {
            uploadMap.put(id, "");
        }
        SpUtils.setMap(mcontext, "uploadMap", uploadMap);
        Log.d(TAG, "prepareUploadData: " + uploadMap.toString());
//        nodeidIndx = 0;
    }

    public static void finishWaypointMission() {
        onMission = false;
        nodeIDs = new ArrayList<>();
//        nodeidIndx = 0;
    }

    /**
     * @param imageBytes
     */
    static void uploadJPG(String imageBytes) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    JSONObject args = new JSONObject();
                    ArrayList position = new ArrayList();
                    DJIKey altitudeKey = FlightControllerKey.create(FlightControllerKey.AIRCRAFT_LOCATION);
                    DJISDKManager.getInstance().getKeyManager().getValue(altitudeKey, new GetCallback() {
                        @Override
                        public void onSuccess(@NonNull Object value) {
                            Log.d(TAG, "get altitude onSuccess: " + value.getClass() + value.toString());
                            if (value instanceof LocationCoordinate3D) {
                                //Do something with ISO value
                                Log.d(TAG, "onSuccess: " + ((LocationCoordinate3D) value).getLatitude());
                                Log.d(TAG, "onSuccess: " + ((LocationCoordinate3D) value).getLongitude());
                                double[] point = GPSUtil.gps84_To_Gcj02(
                                        ((LocationCoordinate3D) value).getLatitude(),
                                        ((LocationCoordinate3D) value).getLongitude());
                                position.add(point[1]);
                                position.add(point[0]);
                            }
                        }
                        @Override
                        public void onFailure(@NonNull DJIError djiError) {
                            Log.d(TAG, "get altitude onFailure: " + djiError.toString());
                        }
                    });
                    curNodeID = nodeIDs.get(CompleteWidgetActivity.waypointcount);
                    args.put("nodeId", curNodeID);
                    args.put("position", position);
                    args.put("suffix", "jpg");
                    args.put("imageBytes", imageBytes);
                    @SuppressLint("SimpleDateFormat")
                    SimpleDateFormat Fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    Date now = new Date();
                    args.put("shootTime", Fmt.format(now));
                    Log.d(TAG, "nodeidIndx: " + CompleteWidgetActivity.waypointcount + "**********" + "nodeIDs.size: " + nodeIDs.size());
                    if (CompleteWidgetActivity.waypointcount == nodeIDs.size())
                        finishWaypointMission();
                    Log.d(TAG, args.toString());
                    RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), args.toString());
                    Request request = new Request.Builder()
                            .addHeader("token", token1)
                            .url(serverAdd + "/uav/add1")
                            .post(body)
                            .build();
                    post(request, new Callback() {
                        @Override
                        public void onFailure(Call call, IOException e) {
                            Log.e(TAG, "uploadJPG onFailure: ", e);
                            reUploadJpg(args.toString());
                            uploadListener.onUploadFailed(e.getMessage());
                        }

                        @Override
                        public void onResponse(Call call, Response response) throws IOException {
                            InputStream is = null;
                            byte[] buf = new byte[2048];
                            int len = 0;

                            final String responseBody = response.body().string();
                            Log.d(TAG, "onResponse: " + responseBody);
                            final JSONObject obj;
                            try {
                                is = response.body().byteStream();
                                long total = response.body().contentLength();
                                long sum = 0;
                                while ((len = is.read(buf)) != -1) {
                                    sum += len;
                                    int progress = (int) (sum * 1.0f / total * 100);
                                    // 下载中
                                    Log.d(TAG, "onResponse: "+progress);
                                    uploadListener.onUploading(progress);
                                }
                                uploadListener.onUploadSuccess();
                                obj = new JSONObject(responseBody);
                                Log.d(TAG, "uploadJPG onResponse: " + obj.toString());
                            } catch (Exception e) {
                                e.printStackTrace();
                            } finally {
                                try {
                                    if (is != null)
                                        is.close();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                    Log.e(TAG, "run: " +  e.getMessage());
                }
            }
        }).start();
    }

    /**
     * 重传图片
     *
     * @param strJson
     */
    private static void reUploadJpg(String strJson) {
        new Thread(() -> {
            try {
                RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), strJson);
                Request request = new Request.Builder()
                        .addHeader("token", token1)
                        .url(serverAdd + "/uav/add1")
                        .post(body)
                        .build();
                post(request, new Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {
                        Log.e(TAG, "RE uploadJPG onFailure: ", e);
                        uploadListener.onUploadFailed(e.getMessage());
                    }
                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        InputStream is = null;
                        byte[] buf = new byte[2048];
                        int len = 0;
                        final String responseBody = response.body().string();
                        Log.d(TAG, "on RE upload Response: " + responseBody);
                        final JSONObject obj;
                        try {
                            is = response.body().byteStream();
                            long total = response.body().contentLength();
                            long sum = 0;
                            while ((len = is.read(buf)) != -1) {
                                sum += len;
                                int progress = (int) (sum * 1.0f / total * 100);
                                // 下载中
                                Log.d(TAG, "onResponse: "+progress);
                                uploadListener.onUploading(progress);
                            }
                            uploadListener.onUploadSuccess();
                            obj = new JSONObject(responseBody);
                            Log.d(TAG, "uploadJPG onResponse: " + obj.toString());
                        } catch (Exception e) {
                            e.printStackTrace();
                            uploadListener.onUploadFailed(e.getMessage());
                        } finally {
                            try {
                                if (is != null)
                                    is.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }

    /**
     * @param code
     * @param status
     */
    public static void updateStatus(String code, int status) {
        new Thread(() -> {
            Log.d(TAG, "updateStatus");
            JSONObject args = new JSONObject();
            try {
                args.put("type", "drone_status_update");
                args.put("code", code);
                args.put("status", status);
                Log.d(TAG, args.toString());
                RabbitMQUtils.sendMessage("uav_app_response", args.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }

            RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), args.toString());
            Request request = new Request.Builder()
                    .addHeader("token", token1)
                    .url(serverAdd + "/uav/update")
                    .post(body)
                    .build();
            post(request, new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    Log.e(TAG, "updateStatus onFailure: ", e);
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    final String responseBody = response.body().string();
                    final JSONObject obj;
                    try {
                        obj = new JSONObject(responseBody);
                        Log.d(TAG, "updateStatus onResponse: " + obj.toString());
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            });
        }).start();
    }

    public interface OnUploadListener {
        void onUploadSuccess();
        void onUploading(int progress);
        void onUploadFailed(String error);
    }
}
